import java.io.*;
import java.util.Arrays;

/**
 * Description:
 * 通讯录管理类
 * 1.包含联系人对象数组和对其进行增删改查等方法。
 * 2.具有封装性特点，处理数组的方法都在此类完成操作且不作数据校验的功能，只完成对应的逻辑.
 * 3.实现联系人数据从本地文件读取和写入。
 *
 * 未实现的功能：
 * 1.不能处理同名联系人的情况。
 * 2.当第一次启动时如果文件里没有任何联系人信息，会报异常。但是捕获处理后好像没什么影响了。
 *
 * User:Jiali
 * Date:2022-08-06-16:01
 */
public class ContactsController {
    private static final int INCREASE_SIZE = 3;
    private static final int DEFAULT_SIZE  = 2;

    private Person[] people = null; //联系人对象数组
    private int currentCount = 0; //当前通讯录人数
    private int currentCapacities = DEFAULT_SIZE;//当前容量


    public ContactsController() {
        people = new Person[DEFAULT_SIZE]; //初始化数组长度
        loadData();
    }

    /**
     * 从本地文件加载联系人数据
     */
    private void loadData(){
        ObjectInputStream in = null;
        try{
            File file = new File("contacts.dat");
            in = new ObjectInputStream(new FileInputStream(file));

            Object obj = null;
            while((obj = in.readObject()) != null){
                expandArray(); //是否需要扩容
                people[currentCount] = (Person)obj;
                currentCount++;
            }
            System.out.println("currentCount:" + currentCount);
            System.out.println("currentCapacities:" + currentCapacities);
        }catch (IOException e){
            e.printStackTrace();
            System.out.println(e.getMessage());
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }finally {
            if(in != null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 将内存中的数据保存到本地文件
     */
    public void saveData(){
        ObjectOutputStream out = null;
        try{
            out = new ObjectOutputStream(new FileOutputStream("contacts.dat"));
            for (int i = 0; i < currentCount; i++) {
                out.writeObject(people[i]);
            }
            //最后写一个null进去代表文件末尾
            out.writeObject(null);
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 扩容数组长度
     */
    private void expandArray(){
        if(currentCount == currentCapacities){
            people = Arrays.copyOf(people,currentCapacities + INCREASE_SIZE);
            currentCapacities += INCREASE_SIZE;
            System.out.println("自动扩容成功，当前容量大小：" + currentCapacities);
        }
    }



    //供外部使用的公共方法 ↓

    /**
     * 新增联系人
     * @param person 联系人对象
     */
    public void insertElement(Person person){
        expandArray();
        people[currentCount++] = person;
    }

    /**
     * 删除指定姓名的联系人
     * @param name
     * @return true:删除成功    false:删除失败（未找到指定姓名的联系人）
     */
    public boolean removeElement(String name){
        for (int i = 0; i < currentCount; i++) {
            if(name.equalsIgnoreCase(people[i].getName())){ //true：有此姓名的联系人
                for(int j = i; j < currentCount - 1; j++){
                    people[j] = people[j + 1];
                }
                //错误代码：
//                people[currentCount] = null;
//                currentCount--;
//                return true;
                //正确代码：
                currentCount--; //人数-1
                people[currentCount] = null; //末尾置空
                return true;
            }
        }
        return false;
    }

    /**
     * 修改指定姓名的联系人信息
     * @param name
     * @param person
     */
    public void modifyElement(String name,Person person){
        for (int i = 0; i < currentCount; i++) {
            if(people[i].getName().equalsIgnoreCase(name)){
                people[i] = person;
            }
        }
    }

    /**
     * 查找指定姓名的联系人
     * @param name
     * @return 找到：Person类对象   未找到：null
     */
    public Person searchByname(String name){
        for (int i = 0; i < currentCount; i++) {
            if(people[i].getName().equalsIgnoreCase(name)){
                return people[i];
            }
        }
        return null;
    }

    /**
     * 按姓名排序联系人数组
     */
    public void sortByName(){
        //当数组中有元素是null值时会报空指针异常
//        Arrays.sort(people, new Comparator<Person>() {
//            @Override
//            public int compare(Person o1, Person o2) {
//                return o1.getName().compareTo(o2.getName());
//            }
//        });

        for (int i = 0; i < currentCount - 1; i++) {
            boolean flag = true; //假设本趟数组是有序的
            for (int j = 0; j < currentCount - 1 - i; j++){
                if(people[j].getName().compareTo(people[j+1].getName()) > 0){
                    Person temp = people[j];
                    people[j] = people[j+1];
                    people[j+1] = temp;
                    flag = false;
                }
            }
            if(flag){ //true:已经有序了
                return;
            }
        }
    }

    /**
     * 清空联系人数组
     */
    public void clearAll(){
        for (int i = 0; i < currentCount; i++) {
            people[i] = null;
        }
        currentCount = 0;
    }

    /**
     * 获取联系人对象数组
     * @return
     */
    public Person[] getPeople() {
        return people;
    }

    /**
     * 获取当前联系人个数
     * @return
     */
    public int getCurrentCount() {
        return currentCount;
    }

    /**
     * 获取当前存储空间容量
     * @return
     */
    public int getCurrentCapacities() {
        return currentCapacities;
    }

}
